Repository Pattern
Repositoryパターンの目的は
メリット
テストがしやすくなる
DBエンジンの変更に対応しやすくなる
データ操作のロジックが1箇所にまとまり、管理しやすくなる
必要なもの
interface
interfaceを実装するクラスを実装
ServiceClass
作り方
interfaceを作る
interfaceを実装するクラスを実装する
repositoryを実装するサービスクラスを実装する
例:
PersonクラスのRepositoryを実装する
1つだけ取得、全部取得、追加、更新、削除のインターフェースクラスがある。
Salary Service Classで実装するためにPersonクラスを用意する。
Sarary Service ClassでGetSalary()処理を作成する。
code:memo.cs
// データアクセスロジックを抽象化するためのインターフェイス
public interface IRepository<T> {
T GetOne(int id);
IEnumerable<T> GetAll();
void Add(T item);
void Update(T item);
void Delete(T item);
}
code:memo.cs
// IRepository インターフェイスを実装し Entity Framework にアクセスするクラスを作成します。
public class PersonRepository : IRepository<Person> {
private DbContext dbContext;
public PersonRepository() {
this.dbContext = new SampleDbContext();
}
public Person GetOne(int id) {
return this.dbContext.Set<Person>().Find(id);
}
public IEnumerable<Person> GetAll() {
return this.dbContext.Set<Person>().AsEnumerable();
}
public void Add(Person item) {
this.dbContext.Set<Person>.Add(item);
this.dbContext.SubmitChanges();
}
public void Update(Person item) {
this.dbContext.SubmitChanges();
}
public void Delete(Person item) {
this.dbContext.Set<Person>.Remove(item);
this.dbContext.SubmitChanges();
}
}
code:memo.cs
// Repository を操作するビジネス ロジックを作成します。
public class SalaryService {
private IRepository<Person> personRepository;
public class SomeService() {
this.personRepository = new PersonRepository();
}
public class SomeService(IRepository<Person> personRepository) {
this.personRepository = personRepository;
}
public IEnumerable<Salary> GetSalaries() {
// 何かしらのビジネス ロジック
}
}
接続文字列に固有の情報が含まれるため、ビルド サーバーに持っていったときに自動テストが実施できない
連続実行した場合など、データベースのデータによって、テスト結果が左右される可能性がある
アンチパターン
機能やロールで分ける
子テーブルに対して沢山Repositoryを作る
複雑なクエリをRepositoryで頑張って発行する
アプリ固有の複雑な処理はQueryService、エンティティの永続化や取得はRepository
code:memo.java
// 例) ユーザの永続化、参照を行うためのリポジトリ(実装は割愛)
public interface UserRepository {
User findBy(Long userId);
User store(User user);
}
// Repositoryの利用クラス
public class FooService {
private UserRepository userRepository;
public FooService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void registerUser(String userName) {
// Repositoryを利用してUserを保存するが、永続化の方法には左右されない
User user = new User(userName);
userRepository.store(user);
}
}
機能やロールでRepositoryを分ける
code:memo
Post
PostRepostitory
PostScreeningRepository
対策
状態更新に関わる振る舞いはEntityやServiceに実装します。
また、状態の操作に関する処理は可能な限り可視性を制御して無理やり変更が出来ないようにします。
code:memo
Post
PostScreeningService
子テーブルに対して沢山Repositoryを作る
複雑なクエリをRepositoryで頑張って発行する
対策
アプリ固有の複雑な処理はQueryService
エンティティの永続化や取得はRepository
確認用
Q. Repositoryパターンの目的は
[] ロジックと[] ロジックを分離すること
Q. Repositoryパターンのメリット
Q. Repositoryパターンのデメリット
Q. repositoryパターンの作り方
[]1を作る
[]1を実装するための[]2を
参考
Repositoryパターンの目的は
ビジネスロジックとデータアクセスロジックを分離するため
メリット
テストがしやすくなる
DBエンジンの変更に対応しやすくなる
データ操作のロジックが1箇所にまとまり、管理しやすくなる
関連